home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / ColorWarp-c / Think / ColorStars.c next >
Encoding:
Text File  |  1994-12-04  |  9.1 KB  |  394 lines  |  [TEXT/KAHL]

  1. //• PD color star warp program sent to me (Ken Long) by a programmer 
  2. //• on the net, on request.
  3. //• Pretty much generic and common (there are lots of warp programs).
  4. //• Hold down '+' to accelerate, '-' to decelerate, mouse turns, 'q'
  5. //• or click quits.
  6. //• Be sure to run this program in 1 bit mode, too!
  7. //• Add MacTraps and ASNI.
  8.  
  9. //• el warpo.c
  10.  
  11. //• Uses direct screen access; 
  12. //• Needs Apple Macintosh with FPU (not!).  
  13. //• Works without FPU but very slow.
  14. //• Optimized for shipSpeed, not elegance.
  15.  
  16. //• TODO:
  17. //• Don't assume monitor is landscape.
  18. //• improve translation algorithm, use mathematically, graphically
  19. //•     correct algorithm.
  20. //• Use keyboard map.
  21. //• Use integer math?
  22. //• Improve separation of code for different screen depths.
  23. //• Make more structured, but keep code fast.
  24.  
  25. #include <math.h>
  26. #include <Types.h>
  27. #include <Memory.h>
  28. #include <Quickdraw.h>
  29. #include <Fonts.h>
  30. #include <Events.h>
  31. #include <Menus.h>
  32. #include <Windows.h>
  33. #include <TextEdit.h>
  34. #include <Dialogs.h>
  35. #include <OSUtils.h>
  36.  
  37. #define num_stars 180    //• Reduce number for more speed (try 18).
  38.                         
  39. //• Apparent density of star field; number of 'close calls'.
  40. #define density 1            
  41.  
  42. #define max_distance 255    //• Index of last color in 8 bit clut.
  43. #define star_clut_ID 128
  44.  
  45. EventRecord            theEvent;
  46. Boolean                keep_going = true;
  47. RgnHandle            GrayRegion, mBarRgn;
  48. short                *mBarHeightPtr;
  49. short                oldMBarHeight;
  50. Rect                windowBounds;
  51. WindowPtr            theWindow;
  52. short                H_far, V_far;
  53. double                star_H [num_stars] , star_V [num_stars] , distance [num_stars] ;
  54. double                shipSpeed;
  55.  
  56. void HireTheManagers (void);
  57. void HideMenuBar (void);
  58. void ShowMenuBar (void);
  59. void SetUpWindow (void);
  60. long double Randomize (short high);
  61. long double A_B (long double number);
  62. void LoadStars (void);
  63. void HandleEvent (void);
  64. void MainlyLooping (void);
  65. int main (void);
  66.  
  67. void HireTheManagers (void) 
  68. {
  69.     MaxApplZone ();
  70.     InitGraf (&thePort);
  71.     InitFonts ();
  72.     FlushEvents (everyEvent, 0);
  73.     InitWindows ();
  74.     InitMenus ();
  75.     TEInit ();
  76.     InitDialogs (0L);
  77.     InitCursor ();
  78.     MoreMasters ();
  79. }
  80.  
  81. void HideMenuBar (void) 
  82. {
  83.     Rect    mBarRect;
  84.  
  85.     GrayRgn = GetGrayRgn ();
  86.     mBarHeightPtr = (short *) 0x0BAA;
  87.     oldMBarHeight = *mBarHeightPtr;
  88.     *mBarHeightPtr = 0;
  89.     mBarRect = screenBits.bounds;
  90.     mBarRect.bottom = mBarRect.top+oldMBarHeight;
  91.     mBarRgn = NewRgn ();
  92.     RectRgn (mBarRgn, &mBarRect);
  93.     UnionRgn (GrayRgn, mBarRgn, GrayRgn);
  94.     PaintOne (0L, mBarRgn);
  95. }
  96.  
  97. //• Show me the way to the next Whiskey bar.
  98. void ShowMenuBar (void)    
  99. {
  100.     *mBarHeightPtr = oldMBarHeight;
  101.     DiffRgn (GrayRgn, mBarRgn, GrayRgn);
  102.     DisposeRgn (mBarRgn);
  103. }
  104.  
  105. void SetUpWindow (void) 
  106. {
  107.     short    centerx, centery;
  108.  
  109.     windowBounds = screenBits.bounds;
  110.     theWindow = NewWindow (0L, &windowBounds, "\pNameless", true, 
  111.                             plainDBox, (WindowPtr)-1L, true, 0);
  112.     SetPort (theWindow);
  113.     InvertRect (&windowBounds);
  114.     centerx = - (windowBounds.right/2);
  115.     centery = - (windowBounds.bottom/2);
  116.     SetOrigin (centerx, centery);
  117.     H_far = windowBounds.right/2;
  118.     V_far = windowBounds.bottom/2;
  119. }
  120.  
  121. long double Randomize (short high)
  122. {
  123.     long double    rawResult;
  124.  
  125.     rawResult = Random ();
  126.     return ((rawResult * high) / 32768);
  127. }
  128.  
  129. long double A_B (long double number)
  130. {
  131.     if (number < 0) 
  132.     return - number;
  133.         else
  134.     return number;
  135. }
  136.  
  137. void LoadStars (void)        //• Could amount to trillions of tons!
  138. {
  139.     short    i;
  140.  
  141.     for (i = 0; i < num_stars; i++) 
  142.     {
  143.         star_H [i] = Randomize (H_far);
  144.         star_V [i] = Randomize (V_far);
  145.         distance [i] = Randomize (max_distance);
  146.     }
  147. }
  148.  
  149. void HandleEvent () 
  150. {
  151.     char    theChar;
  152.  
  153.     switch (theEvent.what) 
  154.     {
  155.         case mouseDown:
  156.             keep_going = FALSE;
  157.         break;
  158.         
  159.         case keyDown:
  160.         case autoKey:
  161.             theChar = (theEvent.message & charCodeMask);
  162.             if (theChar == '+') 
  163.                 shipSpeed += 0.1;
  164.             if (theChar == '-') 
  165.                 shipSpeed -= 0.1;
  166.             if (theChar == 'q') 
  167.                 keep_going = FALSE;
  168.         break;
  169.             
  170.         default:
  171.         break;
  172.     }
  173. }
  174.  
  175. void MainlyLooping (void)        //• Loop 'til you poop!
  176. {
  177.     Point mouseLoc;
  178.     short A_B_H, A_B_V;
  179.     short dark, gray, x_edge, y_edge, diagonal, j, k;
  180.     double mx, my, tempx, tempy, temp, sin_rotate, cos_rotate;
  181.     register short i;
  182.     
  183.     //• graphics vars
  184.     GDHandle        theGDevice;
  185.     PixMapHandle    thePixMap;
  186.     unsigned char *drawAddr;
  187.     unsigned char *baseAddr;
  188.     unsigned long rowBytes;
  189.     short            depth;
  190.     Size            mapSize;
  191.     unsigned char mask;
  192.     CTabHandle        starclut;
  193.  
  194.     //• initial settings.
  195.     LoadStars ();
  196.     
  197.     SetEventMask (mDownMask + keyDownMask + autoKeyMask);
  198.     shipSpeed = 2;
  199.     diagonal = (short) sqrt (((long double) H_far * H_far) + 
  200.                          ((long double) V_far * V_far));
  201.     x_edge = H_far - 10;
  202.     y_edge = V_far - 10;
  203.     
  204.     H_far -= 2;
  205.     V_far -= 2;
  206.  
  207.     //• Gqet info about current device to be drawn to.
  208.     theGDevice = GetGDevice ();
  209.     thePixMap = (*theGDevice)->gdPMap;
  210.     baseAddr = (*thePixMap)->baseAddr;
  211.     rowBytes = (unsigned long)  ((*thePixMap) ->rowBytes & 0x3FFF);
  212.     depth = (*thePixMap) ->pixelSize;
  213.     mapSize = rowBytes*screenBits.bounds.bottom;
  214.  
  215.     //• set color table to star grays if device is 8 bit.
  216.     if (depth == 8) 
  217.     {
  218.             starclut = GetResource ('clut', star_clut_ID);
  219.             SetEntries (-1, ((*starclut)->ctSize) +1, (*starclut)->ctTable);
  220.     }
  221.  
  222.     if (depth != 8 && depth != 1) 
  223.         keep_going = false;
  224.  
  225.     //• main loop.
  226.     while (keep_going == true) 
  227.     {
  228.         //• handle user input.
  229.         if (GetNextEvent (everyEvent, &theEvent)) 
  230.             HandleEvent ();
  231.             GetMouse (&mouseLoc);
  232.             mx = ((double) mouseLoc.h / 420);
  233.             if (A_B (mouseLoc.h) < 2) 
  234.                 mx = 0;
  235.                 my = ((double) mouseLoc.v / 8);
  236.                 sin_rotate = sin (mx);
  237.                 cos_rotate = cos (mx);
  238.     
  239.                 //• cycle through list of stars.
  240.                 for (i = 0; i < num_stars; i++) 
  241.                 {
  242.                     A_B_H = star_H [i] + H_far;
  243.                     A_B_V = star_V [i] + V_far;
  244.                 
  245.                     //• erase star
  246.                     if ((A_B (star_V [i]) <V_far) && (A_B (star_H [i]) <H_far)) 
  247.                     {
  248.                         switch (depth) 
  249.                         {
  250.                             case 1:
  251.                                 drawAddr = baseAddr+ (A_B_V * rowBytes + A_B_H/8L);
  252.                                 mask = (unsigned char) 1 << (7- (A_B_H% 8));
  253.                                 *drawAddr |= mask;
  254.                             break;
  255.                             
  256.                             case 8:
  257.                                 drawAddr = baseAddr+A_B_V * 
  258.                                          rowBytes + A_B_H;
  259.                                 for (j = 1; j <= 3; j++) 
  260.                                 {
  261.                                     for (k = 1; k <= 3; k++) 
  262.                                     {
  263.                                         *drawAddr = 0xFF;
  264.                                         drawAddr++;
  265.                                     }
  266.                                     drawAddr -= 3;
  267.                                     drawAddr += rowBytes;
  268.                                 }
  269.                             break;
  270.                             default:
  271.                             break;
  272.                         }
  273.                     }
  274.                                 
  275.                     //• update star's mapped projection.
  276.                     temp = (density + shipSpeed + distance [i]) / 
  277.                            (distance [i] + density);
  278.                          
  279.                     star_H [i] = star_H [i] *temp;
  280.                     star_V [i] = star_V [i] *temp + my;
  281.                     temp = star_H [i] ;
  282.                     
  283.                     star_H [i] = star_H [i] *cos_rotate + 
  284.                                  star_V [i] *sin_rotate;
  285.                                  
  286.                     star_V [i] = -temp * sin_rotate + star_V [i] * cos_rotate;
  287.                     distance [i] -= shipSpeed;
  288.                 
  289.                     //• if offscreen or past, generate new star*/
  290.                     if ((A_B (star_H [i]) > diagonal) ||
  291.                          (A_B (star_V [i]) > diagonal) ||
  292.                          (distance [i] < 0) ||
  293.                          (distance [i] > max_distance)) 
  294.                     {
  295.                         if (shipSpeed > 0)     //• going forwards.
  296.                         {
  297.                             star_H [i] = Randomize (x_edge);
  298.                             star_V [i] = Randomize (y_edge) - my;
  299.                             distance [i] = max_distance;
  300.                         }
  301.                         else        //• going backwards (not finished).
  302.                             {
  303.                                 if (Randomize (1) > 0) 
  304.                                 {
  305.                                     star_H [i] = Randomize (H_far);
  306.                                     if (Randomize (1) > 0) 
  307.                                         star_V [i] = V_far;
  308.                                     else
  309.                                         star_V [i] = -V_far;
  310.                                 }
  311.                                 else
  312.                                     {
  313.                                         star_V [i] = Randomize (V_far);
  314.                                         if (Randomize (1) < 0) 
  315.                                             star_H [i] = H_far;
  316.                                         else
  317.                                             star_H [i] =- H_far;
  318.                                 }
  319.                                 distance [i] = A_B (Randomize (max_distance - 20)) +20;
  320.                             }
  321.                         }
  322.                     
  323.                         //• redraw star at new position
  324.                         A_B_H = star_H [i] + H_far;
  325.                         A_B_V = star_V [i] + V_far;
  326.                         if ((A_B (star_V [i]) < V_far) && (A_B (star_H [i]) < H_far)) 
  327.                         {
  328.                             switch (depth) 
  329.                             {
  330.                                 case 1:
  331.                                     drawAddr = baseAddr + 
  332.                                               (A_B_V * 
  333.                                                rowBytes + 
  334.                                                A_B_H / 8L);
  335.                                                
  336.                                     mask = (unsigned char) 1 << 
  337.                                            (7 - (A_B_H % 8));
  338.                                            
  339.                                     *drawAddr ^= mask;
  340.                                 break;
  341.                                 
  342.                                 case 8:
  343.                                     dark = max_distance - 
  344.                                          ((max_distance - 
  345.                                            distance [i]) / 6);
  346.                                            
  347.                                     gray = max_distance - 
  348.                                          ((max_distance - 
  349.                                            distance [i]) / 4);
  350.                                            
  351.                                     drawAddr = baseAddr + 
  352.                                                A_B_V * 
  353.                                                rowBytes + 
  354.                                                A_B_H;
  355.                                                
  356.                                     *drawAddr = dark;
  357.                                     drawAddr++;
  358.                                     *drawAddr = gray;
  359.                                     drawAddr++;
  360.                                     *drawAddr = dark;
  361.                                     drawAddr += rowBytes - 2;
  362.                                     *drawAddr = gray;
  363.                                     drawAddr++;
  364.                                     *drawAddr = distance [i] ;
  365.                                     drawAddr++;
  366.                                     *drawAddr = gray;
  367.                                     drawAddr += rowBytes - 2;
  368.                                     *drawAddr = dark;
  369.                                     drawAddr++;
  370.                                     *drawAddr = gray;
  371.                                     drawAddr++;
  372.                                     *drawAddr = dark;
  373.                                 break;
  374.                                 
  375.                                 default:
  376.                                 break;
  377.                             }
  378.                         }
  379.                     }
  380.     }
  381.     SetEventMask (everyEvent);
  382. }
  383.  
  384. int main (void)
  385. {
  386.     HireTheManagers ();        //• These guys Macintize.
  387.     HideMenuBar ();            //• Get rid of this interference.
  388.     SetUpWindow ();            //• A place to draw.
  389.     HideCursor ();            //• Swat that fly!
  390.     MainlyLooping ();        //• Get yer mo jo workin'.
  391.     ShowCursor ();            //• Return of the Fly!
  392.     ShowMenuBar ();            //• Get ready for Finder's keepers.
  393. }
  394.